/* $Header: clock_ui.c,v 2.2 01/10/02 10:26:00 przybyls Exp $ */

/***********************************************************************/
/*                                                                     */
/*                  Copyright Hewlett-Packard Co. 1991                 */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/* MODULE NAME: clock_ui.c                                             */
/* ============                                                        */
/*                                                                     */
/* Author:                                                             */
/*                                                                     */
/* MODULE PURPOSE: Access functions for clock table and clock.         */
/*                                                                     */
/*                                                                     */
/*                                                                     */
/*                                                                     */
/***********************************************************************/


/*****************************/
/*   GLOBAL INCLUDE FILES    */
/*****************************/

#include  <typedefs.h>
#include  <error.h>
#include  <p_wkfile.h>
#include  <wkfile.h>
#include  <p_status.h>
#include  <i_op.h>
#include  <iomap.h>
#include  <exception.h>
#include  <timetable.h>
#include  <clock_ui.h>
#include <mio.h>
#include <cmd_set.h>
#include  <als.h>
#include  <det_ui.h>
#include  <sequence.h>

/*****************************/
/*   LOCAL INCLUDE FILES     */
/*****************************/


/*****************************/
/*   GLOBAL VARIABLES        */
/*****************************/

#pragma SECTION UDATA=pfail

BIT8    Clock_Hosed;
BIT8    Calendar_Hosed;

#pragma SECTION UNDO

DATETIME DateTime;

/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/


/*****************************/
/*   LOCAL DEFINES           */
/*****************************/

/*****************************/
/*   STATIC VARIABLES        */
/*****************************/


/*****************************/
/*   IMPLEMENT SECTION       */
/*****************************/


/*-----begin change by wangwei-----------*/
static const DATETIME Uninitialized_Date_Time = {0, 0, 0, 0, 0, 0};


/* The following function is used to initialize datetime values.  */
/* It indicates that a datetime value has not been set.           */

void InitializeDateTime( DATETIME *pdatetime )
{
   INTERRUPTS_OFF
      *pdatetime = Uninitialized_Date_Time;
   INTERRUPTS_ON
}
void SetDateTime( DATETIME *datetime )
{
   INTERRUPTS_OFF
      *datetime = DateTime;
   INTERRUPTS_ON
}

INT32 GetTime (DATETIME *datetime )
{
   INT32 time;
   time = datetime->second + (100 * datetime->minute) + (10000 * datetime->hour);
   return time;
}
INT32 GetDate ( DATETIME *datetime )
{
   INT32 date;
   date = datetime->year + (100 * datetime->month) + (10000 * datetime->day);
   return date;
}
BIT8 DateIsUninitialized (DATETIME when)//in clktbl/clock_ui.c
{
   if (when.month == 0)
   {
      return TRUE;
   }
   else
   {
      return FALSE;
   }
}
/*
DATETIME TimeFromSeconds ( U_INT32 seconds )//in clktbl/clock_ui.c
{
  printf("call TimeFromSeconds\n");
   DATETIME date;
   date.year = 2009; date.month = 9;date.day = 15;date.hour = 13;date.minute = 10;date.second = 10;
   return date;
}
*/
U_INT32 SecondsSince1980 (DATETIME now)
{
   /* NOTE: U_INT32 will hold 136 years in seconds.     */

   U_INT32  seconds;

   if ( now.month == 0 )
   {
      return 0;    /* invalid date  */
   }
   else
   {
      seconds = now.second + (60 * now.minute) + (3600 * now.hour) +
                (24*3600 * (now.day - 1));

      if (now.month > 1)      /* Jan */
      {
         seconds += 31 * 24 * 3600;
      }

      if (now.month > 2)      /* Feb */
      {
         seconds += 28 * 24 * 3600;

         if ((now.year % 4) == 0)
         {
            seconds += 24 * 3600;
         }
      }

      if (now.month > 3)      /* Mar */
      {
         seconds += 31 * 24 * 3600;
      }

      if (now.month > 4)      /* April */
      {
         seconds += 30 * 24 * 3600;
      }

      if (now.month > 5)      /* May */
      {
         seconds += 31 * 24 * 3600;
      }

      if (now.month > 6)      /* June */
      {
         seconds += 30 * 24 * 3600;
      }

      if (now.month > 7)      /* July */
      {
         seconds += 31 * 24 * 3600;
      }

      if (now.month > 8)      /* August */
      {
         seconds += 31 * 24 * 3600;
      }

      if (now.month > 9)      /* Sept */
      {
         seconds += 30 * 24 * 3600;
      }

      if (now.month > 10)     /* Oct */
      {
         seconds += 31 * 24 * 3600;
      }

      if (now.month > 11)     /* Nov */
      {
         seconds += 30 * 24 * 3600;
      }

/*    if (now.year < FROZEN_YEAR)   VIREO has FROZEN_YEAR >= 00, always add 100 */

      now.year += 100;

      now.year -= 80;   /* makes now.year = # years since 1980 */

      seconds += 365 * 24 * 3600 * now.year;

      if (now.year > 0)    /* Handles leap years for years > 1980 */
      {
         seconds += 24 * 3600 * (((now.year - 1)/4) + 1);
         /* the (now.year-1)/4 +1 above yields a sequence of 1,1,1,1,2,2,2,2,3,... */
         /* for the years 81, 82, 83, 84, 85, ...  The leap year for the PRESENT   */
         /* year is handled in the month calculation above.                        */
      }

      return seconds;
   }
}

DATETIME TimeFromSeconds ( U_INT32 seconds )
{
   U_INT32 seconds_left;

   U_INT8 quad_year;
   U_INT8 year;
   U_INT8 month;

   DATETIME date;


#define SEC_PER_MIN                ( 60 )

#define MIN_PER_HOUR               ( 60 )
#define SEC_PER_HOUR               ( SEC_PER_MIN * MIN_PER_HOUR )

#define HOUR_PER_DAY               ( 24 )
#define SEC_PER_DAY                ( SEC_PER_HOUR * HOUR_PER_DAY )

#define DAY_PER_QUAD_YEAR          ( 4 * 365 + 1 )
#define SEC_PER_QUAD_YEAR          ( SEC_PER_DAY * DAY_PER_QUAD_YEAR )

#define DAY_PER_YEAR               ( 365 )
#define SEC_PER_YEAR               ( SEC_PER_DAY * DAY_PER_YEAR )

#define SEC_PER_LEAP_YEAR          ( ( 1 + DAY_PER_YEAR ) * SEC_PER_DAY )


                                 /* x    J    F    M    A    M    J    J    A    S    O    N    D   */
static const Day_Per_LY_Month[] = { 0,  31,  60,  91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };
static const Day_Per_Month[]    = { 0,  31,  59,  90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };

    seconds_left = seconds;

    quad_year    = seconds_left / SEC_PER_QUAD_YEAR;
    seconds_left = seconds_left % SEC_PER_QUAD_YEAR;

        /* the year calc below does not look for the leap day */
        /* so, if it would have happened, account for it here */

    if ( seconds_left > SEC_PER_LEAP_YEAR ) seconds_left -= SEC_PER_DAY;

    year         = seconds_left / SEC_PER_YEAR;
    seconds_left = seconds_left % SEC_PER_YEAR;

    date.year    = ( ( quad_year * 4 ) + year + 80 ) % 100;

    if ( year == 0 )  /* leap year! */
    {
       for ( month = 1 ; month <= 12 ; month++ )
       {
           if (( Day_Per_LY_Month [ month ] * SEC_PER_DAY ) > (INT32) seconds_left )
           {
               seconds_left = seconds_left - ( SEC_PER_DAY * Day_Per_LY_Month [ month -1 ] );
               break;
           }
       }
    }
    else
    {
       for ( month = 1 ; month <= 12 ; month++ )
       {
           if (( Day_Per_Month [ month ] * SEC_PER_DAY ) > (INT32) seconds_left )
           {
               seconds_left = seconds_left - ( SEC_PER_DAY * Day_Per_Month [ month -1 ] );
               break;
           }
       }
    }

    if ( seconds == 0 ) month = 0;   /* if incoming value is zero, return uninitialized date */
    date.month   = month;

    date.day     = seconds_left / SEC_PER_DAY + 1;
    seconds_left = seconds_left % SEC_PER_DAY;

    date.hour    = seconds_left / SEC_PER_HOUR;
    seconds_left = seconds_left % SEC_PER_HOUR;

    date.minute  = seconds_left / SEC_PER_MIN;
    seconds_left = seconds_left % SEC_PER_MIN;

    date.second  = seconds_left;


    return date;


}

/*-----end change------------------------*/

